﻿//*************************************************************************
//面向服务的协作式智能交通系统仿真软件SoC-ITSS v2.1 alpha
//发布单位：西北工业大学--巴黎高科MINES机器人与群智能系统联合实验室
//团队负责人：张凯龙 Zhang Kailong
//团队成员：张大方、杨安胜、王敏、谢策、王雨佳、谢尘玉等
//联系我们：kl.zhang@nwpu.edu.cn
//2012-2021
//*************************************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CyberCarSimulation.Bean;
using System.Xml;
using CyberCarSimulation.RoadModel;
using System.Drawing;

//*******************************************************
//
//文件名(File Name):           LoadXML.cs
//
//数据表(Tables):              nothing 
//
//          修改理由：         解析路口In信息
//
//          修改理由：         解析连接关系
//
//*******************************************************

namespace CyberCarSimulation.Simulation
{
    class LoadXML
    {

        /// <summary>
        /// 根据输入的URL将地图信息写入全局变量中
        /// </summary>
        /// <param name="URL"></param>
        /// <returns></returns>
        public bool LoadMapInformation(string URL)
        {
            if (URL == null)
            {
                return false;
            }

            //初始化存储地图信息的全局变量
            MainData.Map = new Map();



            //读取XML数据
            XmlDocument XmlDoc = new XmlDocument();
            XmlDoc.Load(URL);

            //解析config.xml数据
            XmlNode root = XmlDoc.SelectSingleNode("Map");
            XmlNodeList nodeList = root.ChildNodes;
            foreach (XmlNode InfomationType in nodeList)
            {
                //解析Map的信息
                if ("MapInfo".Equals(InfomationType.Name))
                {
                    ParseMapXML(InfomationType);
                }

                //解析WayList信息
                if ("WayList".Equals(InfomationType.Name))
                {
                    ParseWayXML(InfomationType);
                }

                //解析IntersectionList信息
                if ("IntersectionList".Equals(InfomationType.Name))
                {
                    ParseIntersectionXML(InfomationType);
                }

                //解析Relation信息
                if ("RelationMatrix".Equals(InfomationType.Name))
                {
                    ParseRelationXML(InfomationType);
                }
            }
            return true;
        }

        //解析XML道路信息的Map
        public bool ParseMapXML(XmlNode InfomationType)
        {
            foreach(XmlNode MapInfo in InfomationType.ChildNodes)
            {
                if ("ID".Equals(MapInfo.Name)) 
                {
                    string ID = MapInfo.InnerText;
                    MainData.Map.SetID(ID);
                }

                if ("Height".Equals(MapInfo.Name))
                {
                    string Height = MapInfo.InnerText;
                    MainData.Map.SetHeight(int.Parse(Height));
                }

                if ("Width".Equals(MapInfo.Name))
                {
                    string Width = MapInfo.InnerText;
                    MainData.Map.SetWidth(int.Parse(Width));
                }

                if ("IP".Equals(MapInfo.Name))
                {
                    string IP = MapInfo.InnerText;
                    MainData.Map.SetIP(IP);
                }

                if ("LengthIntNum".Equals(MapInfo.Name))
                {
                    string LengthIntNum = MapInfo.InnerText;
                    MainData.Map.SetLengthIntNum(int.Parse(LengthIntNum));
                }

                if ("WidthIntNum".Equals(MapInfo.Name))
                {
                    string WidthIntNum = MapInfo.InnerText;
                    MainData.Map.SetWidthIntNum(int.Parse(WidthIntNum));
                }

                if ("IntNum".Equals(MapInfo.Name)) 
                {
                    string IntNum = MapInfo.InnerText;
                    MainData.Map.SetIntNum(int.Parse(IntNum));
                }

            }
            return true;
        }


        //解析XML道路信息中的Way
        public bool ParseWayXML(XmlNode InfomationType)
        {
            //初始化存储对象
            List<Way> WayList = new List<Way>();

            //对WayList中的每一个Way解析
            XmlNodeList WayNodeList = InfomationType.ChildNodes;
            foreach (XmlNode WayNode in WayNodeList)
            {
                //获取Way的ID
                XmlElement WayElement = (XmlElement)WayNode;
                string WayID = WayElement.GetAttribute("id");
                Way Way = new Way();
                Way.SetID(WayID);

                foreach (XmlNode WayInfo in WayNode)
                {
                    if ("Angle".Equals(WayInfo.Name))
                    {
                        string Angle = WayInfo.InnerText;
                        Way.SetAngle(int.Parse(Angle));
                    }

                    if ("StartPonit1".Equals(WayInfo.Name))
                    {
                        string StartPonit = WayInfo.InnerText;
                        string[] sArray = StartPonit.Split(' ');
                        PointF Point = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                        Way.SetStartPoint1(Point);
                    }

                    if ("StartPonit2".Equals(WayInfo.Name))
                    {
                        string StartPonit = WayInfo.InnerText;
                        string[] sArray = StartPonit.Split(' ');
                        PointF Point = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                        Way.SetStartPoint2(Point);
                    }

                    if ("EndPonit1".Equals(WayInfo.Name))
                    {
                        string EndPonit = WayInfo.InnerText;
                        string[] sArray = EndPonit.Split(' ');
                        PointF Point = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                        Way.SetEndPoint1(Point);
                    }

                    if ("EndPonit2".Equals(WayInfo.Name))
                    {
                        string EndPonit = WayInfo.InnerText;
                        string[] sArray = EndPonit.Split(' ');
                        PointF Point = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                        Way.SetEndPoint2(Point);
                    }

                    if ("StartInterId".Equals(WayInfo.Name))
                    {
                        string StartInterId = WayInfo.InnerText;
                        Way.SetStartInter(StartInterId);
                    }

                    if ("EndInterId".Equals(WayInfo.Name))
                    {
                        string EndInterId = WayInfo.InnerText;
                        Way.SetEndInter(EndInterId);
                    }

                    if ("Weight".Equals(WayInfo.Name))
                    {
                        float Weight = float.Parse(WayInfo.InnerText);
                        Way.SetWeight(Weight);
                    }

                    if ("Length".Equals(WayInfo.Name))
                    {
                        float Length = float.Parse(WayInfo.InnerText);
                        Way.SetLength(Length);
                    }

                    if ("Width".Equals(WayInfo.Name))
                    {
                        float Width = float.Parse(WayInfo.InnerText);
                        Way.SetWidth(Width);
                    }

                    if ("Shape".Equals(WayInfo.Name))
                    {
                        string Shape = WayInfo.InnerText;
                        Way.SetShape(Shape);
                    }

                    if ("LaneList".Equals(WayInfo.Name))
                    {
                        //初始化存储对象
                       List<Lane> LaneList = new List<Lane>();
 
                       XmlNodeList LaneListNode = WayInfo.ChildNodes;
                       foreach(XmlNode LaneNode in LaneListNode)
                       {

                           if("Lane".Equals(LaneNode.Name))
                           {
                               //获取Lane的ID
                               XmlElement LaneElement = (XmlElement)LaneNode;
                               string LaneID = LaneElement.GetAttribute("id");
                               Lane Lane = new Lane();
                               Lane.SetID(LaneID);

                               foreach (XmlNode LaneInfo in LaneNode.ChildNodes)
                               {
                                   if ("WayID".Equals(LaneInfo.Name))
                                   {
                                       string LWayID = LaneInfo.InnerText;
                                       Lane.SetWayID(LWayID);
                                   }

                                   if ("Angle".Equals(LaneInfo.Name))
                                   {
                                       string Angle = LaneInfo.InnerText;
                                       Lane.SetAngle(int.Parse(Angle));
                                   }

                                   if ("StartPonit1".Equals(LaneInfo.Name))
                                   {
                                       string StartPonit = LaneInfo.InnerText;
                                       string[] sArray = StartPonit.Split(' ');
                                       PointF Point = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                                       Lane.SetStartPoint1(Point);
                                    }

                                   if ("StartPonit2".Equals(LaneInfo.Name))
                                   {
                                       string StartPonit = LaneInfo.InnerText;
                                       string[] sArray = StartPonit.Split(' ');
                                       PointF Point = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                                       Lane.SetStartPoint2(Point);
                                   }

                                   if ("EndPoint1".Equals(LaneInfo.Name))
                                   {
                                       string EndPonit = LaneInfo.InnerText;
                                       string[] sArray = EndPonit.Split(' ');
                                       PointF Point = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                                       Lane.SetEndPoint1(Point);
                                   }

                                   if ("EndPoint2".Equals(LaneInfo.Name))
                                   {
                                       string EndPonit = LaneInfo.InnerText;
                                       string[] sArray = EndPonit.Split(' ');
                                       PointF Point = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                                       Lane.SetEndPoint2(Point);
                                   }

                                   if ("Length".Equals(LaneInfo.Name))
                                   {
                                       string Length = LaneInfo.InnerText;
                                       Lane.SetLength(float.Parse(Length));
                                   }

                                   if ("Width".Equals(LaneInfo.Name))
                                   {
                                       string Width = LaneInfo.InnerText;
                                       Lane.SetWidth(float.Parse(Width));
                                   }

                                   if ("StartCriticalID".Equals(LaneInfo.Name))
                                   {
                                       string StartCriticalID = LaneInfo.InnerText;
                                       Lane.SetStartCriticalID(StartCriticalID);
                                   }

                                   if ("EndCriticalID".Equals(LaneInfo.Name))
                                   {
                                       string EndCriticalID = LaneInfo.InnerText;
                                       Lane.SetEndCriticalID(EndCriticalID);
                                   }

                                   if ("LType".Equals(LaneInfo.Name))
                                   {
                                       string EndCriticalID = LaneInfo.InnerText;
                                       if (EndCriticalID.Equals("1"))
                                       {
                                           Lane.SetLType("Enter");
                                       }
                                       if (EndCriticalID.Equals("2"))
                                       {
                                           Lane.SetLType("Leave");
                                       } 
                                       if (EndCriticalID.Equals("3"))
                                       {
                                           Lane.SetLType("Center");
                                       }
                                   }

                               }
                               LaneList.Add(Lane);
                           }
                           Way.SetLaneList(LaneList);
                       }
                        
                    }
                }
                WayList.Add(Way);
            }
            MainData.TotalWayList = WayList;
            //MainData.Map.SetWayList(WayList);
            return true;
        }

        //解析XML道路信息中的路口
        public bool ParseIntersectionXML(XmlNode InfomationType)
        {
             //初始化存储对象
            List<Intersection> IntersectionList = new List<Intersection>();

            //对IntersectionList中的每一个Way解析
            XmlNodeList IntersectionNodeList = InfomationType.ChildNodes;
            foreach (XmlNode IntersectionNode in IntersectionNodeList)
            {
                //获取Intersection的ID
                XmlElement IntersectionElement = (XmlElement)IntersectionNode;
                string ID = IntersectionElement.GetAttribute("id");
                Intersection Intersection = new Intersection(ID);
                Intersection.SetID(ID);

                foreach (XmlNode IntersectionInfo in IntersectionNode)
                {
                    if ("Point1".Equals(IntersectionInfo.Name))
                    {
                        string Ponit= IntersectionInfo.InnerText;
                        if (Ponit != "") 
                        {
                            string[] sArray = Ponit.Split(' ');
                            PointF Point1 = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                            Intersection.SetPoint1(Point1);
                        }
                    }

                    if ("Point2".Equals(IntersectionInfo.Name))
                    {
                        string Ponit = IntersectionInfo.InnerText;
                        if (Ponit != "")
                        {
                            string[] sArray = Ponit.Split(' ');
                            PointF Point2 = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                            Intersection.SetPoint2(Point2);
                        }
                    }

                    if ("Point3".Equals(IntersectionInfo.Name))
                    {
                        string Ponit = IntersectionInfo.InnerText;
                        if (Ponit != "")
                        {
                            string[] sArray = Ponit.Split(' ');
                            PointF Point3 = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                            Intersection.SetPoint3(Point3);
                        }
                    }

                    if ("Point4".Equals(IntersectionInfo.Name))
                    {
                        string Ponit = IntersectionInfo.InnerText;
                        if (Ponit != "")
                        {
                            string[] sArray = Ponit.Split(' ');
                            PointF Point4 = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                            Intersection.SetPoint4(Point4);
                        }
                    }

                    if ("Length".Equals(IntersectionInfo.Name))
                    {

                        string Length = IntersectionInfo.InnerText;
                        if (Length != "")
                        {
                            Intersection.SetLength(float.Parse(Length));
                        }
                    }

                    if ("Shape".Equals(IntersectionInfo.Name))
                    {
                        string Shape = IntersectionInfo.InnerText;
                        Intersection.SetShape(Shape);
                    }

                    if ("Type".Equals(IntersectionInfo.Name))
                    {
                        string Type = IntersectionInfo.InnerText;
                        Intersection.SetIType(Type);
                    }

                    if ("CriticalNum".Equals(IntersectionInfo.Name))
                    {
                        string CriticalNum = IntersectionInfo.InnerText;
                        Intersection.SetCriticalNumber(int.Parse(CriticalNum));
                    }

                    if ("CriticalList".Equals(IntersectionInfo.Name))
                    {
                        List<Critical> CriticalList = new List<Critical>();
                        XmlNodeList CriticalListNode = IntersectionInfo.ChildNodes;

                        if (CriticalListNode.Count != 0)
                        {
                                                       
                            foreach (XmlNode CriticalNode in CriticalListNode) 
                            { 

                                
                                //获取Critical的ID
                                XmlElement CriticalElement = (XmlElement)CriticalNode;
                                string CID = CriticalElement.GetAttribute("id");
                                Critical Critical = new Critical();
                                Critical.SetID(CID);
                                                              

                                foreach(XmlNode CriticalInfo in CriticalNode)
                                {

                                    if ("IntersectionID".Equals(CriticalInfo.Name))
                                    {
                                        string IntersectionID = CriticalInfo.InnerText;
                                        Critical.SetIntersectionID(IntersectionID);
                                    }

                                    if ("RelativeID".Equals(CriticalInfo.Name))
                                    {
                                        string RelativeID = CriticalInfo.InnerText;
                                        Critical.SetRelativeID(int.Parse(RelativeID));
                                    }

                                    if ("EnterLaneID".Equals(CriticalInfo.Name))
                                    {
                                        string EnterLaneID = CriticalInfo.InnerText;
                                        Critical.SetEnterLaneID(EnterLaneID);
                                    }

                                    if ("ExitLaneID".Equals(CriticalInfo.Name))
                                    {
                                        string ExitLaneID = CriticalInfo.InnerText;
                                        Critical.SetExitLaneID(ExitLaneID);
                                    }

                                    if ("Length".Equals(CriticalInfo.Name))
                                    {
                                        string Length = CriticalInfo.InnerText;
                                        Critical.SetLength(float.Parse(Length));
                                    }

                                    if ("Width".Equals(CriticalInfo.Name))
                                    {
                                        string Width = CriticalInfo.InnerText;
                                        Critical.SetWidth(float.Parse(Width));
                                    }

                                    if ("Point1".Equals(CriticalInfo.Name))
                                    {
                                        string Ponit = CriticalInfo.InnerText;
                                        string[] sArray = Ponit.Split(' ');
                                        PointF Point1 = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                                        Critical.SetPoint1(Point1);
                                    }

                                    if ("Point2".Equals(CriticalInfo.Name))
                                    {
                                        string Ponit = CriticalInfo.InnerText;
                                        string[] sArray = Ponit.Split(' ');
                                        PointF Point2 = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                                        Critical.SetPoint2(Point2);
                                    }

                                    if ("Point3".Equals(CriticalInfo.Name))
                                    {
                                        string Ponit = CriticalInfo.InnerText;
                                        string[] sArray = Ponit.Split(' ');
                                        PointF Point3 = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                                        Critical.SetPoint3(Point3);
                                    }

                                    if ("Point4".Equals(CriticalInfo.Name))
                                    {
                                        string Ponit = CriticalInfo.InnerText;
                                        string[] sArray = Ponit.Split(' ');
                                        PointF Point4 = new PointF(float.Parse(sArray[0]), float.Parse(sArray[1]));
                                        Critical.SetPoint4(Point4);
                                    }

                                }
                                CriticalList.Add(Critical);   
                            }

                        }
                        Intersection.SetCriticalList(CriticalList);
                    }
                }
                IntersectionList.Add(Intersection);
            }
            MainData.Map.SetIntersectionList(IntersectionList);
            return true;
        }

        //解析XML道路信息中的连接关系
        public bool ParseRelationXML(XmlNode InfomationType)
        {
            //对IntersectionList中的每一个Way解析
            XmlNodeList RelationMatrixNodeList = InfomationType.ChildNodes;
            //设置数组大小
            int Row = 0;       //行
            int Column = 0;    //列

            foreach (XmlNode RealtionMatrixNode in RelationMatrixNodeList)
            {

                
                if ("RelationShip".Equals(RealtionMatrixNode.Name))
                {
                    Row = RealtionMatrixNode.ChildNodes.Count;
                    foreach (XmlNode TestNode in RealtionMatrixNode.ChildNodes) 
                    {
                        Column = TestNode.ChildNodes.Count;
                        break;
                    }
                }

                //第一次循环得到了长宽
                //drerc 循环长宽重置了
                  
                
                int TempR1 = 0;  //行
                int TempC1 = 0;  //列
                if ("RelationShip".Equals(RealtionMatrixNode.Name))
                {
                    //初始化存储数组
                    string[,] RelationShip = new string[Row, Column];

                    foreach(XmlNode ItemListNode in RealtionMatrixNode.ChildNodes)
                    {
                        foreach (XmlNode ItemNode in ItemListNode.ChildNodes)
                        {
                            string item = ItemNode.InnerText;
                            RelationShip[TempR1,TempC1] = item;
                            TempC1++;
                        }
                        TempC1 = 0;
                        TempR1++;
                    }
                    MainData.Map.SetRelationShip(RelationShip);
                }

                int TempR2 = 0;  //行
                int TempC2 = 0;  //列
                if ("RelationWeight".Equals(RealtionMatrixNode.Name))
                {
                    double[,] RelationWeight = new double[Row, Column];
                    foreach (XmlNode ItemListNode in RealtionMatrixNode.ChildNodes)
                    {
                        foreach (XmlNode ItemNode in ItemListNode.ChildNodes)
                        {
                            string item = ItemNode.InnerText;
                            RelationWeight[TempR2, TempC2] = double.Parse(item);
                            TempC2++;
                        }
                        TempC2 = 0;
                        TempR2++;
                    }
                    MainData.Map.SetRelationWeight(RelationWeight);
                }
            }
            return true;
        }

    }
}
